﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using WebSiteAdminTool.UI.ViewModels.Base;
using System.ComponentModel;
using WebSiteAdminTool.UI.MembershipService;
using System.Collections.ObjectModel;
using WebSiteAdminTool.UI.Utils.Commands;
using WebSiteAdminTool.UI.Services.Messaging;
using WebSiteAdminTool.UI.Services.Messaging.DataManipulationMessages;

namespace WebSiteAdminTool.UI.ViewModels.Security.Users
{
    public class UserManagementViewModel : BaseViewModel
    {
        #region private data

        // data fields
        private int _numberOfUsersOnline = 0;
        private ObservableCollection<UserData> _usersList = null;
        private UserData _selectedUser = null;

        // commands
        private ICommand _doubleClickCommand = null;
        private GenericCommand _alphaFilterAppliedCommand;

        #endregion

        #region public props

        public UserListFilterViewModel UsersListFilter { get; set; }
        public ObservableCollection<UserData> UsersList
        {
            get { return _usersList; }
            set
            {
                _usersList = value;
                RaisePropertyChanged("UsersList");
                RaisePropertyChanged("NumberOfFoundUsers");
            }
        }
        public int NumberOfFoundUsers
        {
            get { return null == UsersList ? 0 : UsersList.Count; }
        }
        public int NumberOfUsersOnline
        {
            get { return _numberOfUsersOnline; }
            set
            {
                _numberOfUsersOnline = value;
                RaisePropertyChanged("NumberOfUsersOnline");
            }
        }
        public UserData SelectedUser
        {
            get { return _selectedUser; }
            set
            {
                if (_selectedUser == value)
                {
                    return;
                }

                _selectedUser = value;
                RaisePropertyChanged("SelectedUser");
                MessageManager.SendMessage(new SelectedItemChangedMessage<UserData>(_selectedUser));
            }
        }
        // commands
        public ICommand DoubleClickCommand { get { return _doubleClickCommand; } }
        public GenericCommand AlphaFilterAppliedCommand { get { return _alphaFilterAppliedCommand; } }

        #endregion

        #region ctors

        public UserManagementViewModel(UserListFilterViewModel filter)
        {
            UsersListFilter = filter;

            base.InitViewModel();
        }

        #endregion

        #region initialization

        protected override void InitializeCommands()
        {
            _doubleClickCommand = new ActionLinkClickedCommand(this.EditUser);
            _alphaFilterAppliedCommand = new GenericCommand(OnAlphaFilterApplied, true);

            base.InitializeCommands();
        }

        protected override void RegisterListeners()
        {
            base.RegisterListeners();

            MessageManager.ListenForNotifications(this, (message) =>
            {
                if (message.Content == CommandsEnum.UserListFilterApplied)
                {
                    this.LoadData();
                }
            });
            MessageManager.RegisterListener<DataObjectCreated<UserData>>(this, message => LoadData());
            MessageManager.RegisterListener<DataObjectUpdated<UserData>>(this, message => LoadData());
            MessageManager.RegisterListener<DataObjectDeleted<UserData>>(this, message => LoadData());
        }

        #endregion

        #region Data Loaders

        protected override void LoadData()
        {
            base.LoadData();

            LoadOnlineUsersNumber();
            LoadUsers(UsersListFilter.SelectedFilterCriteria, UsersListFilter.FilterValue);
        }

        private void LoadOnlineUsersNumber()
        {
            var client = new MembershipServiceClient();
            client.GetNumberOfUsersOnlineCompleted += new EventHandler<GetNumberOfUsersOnlineCompletedEventArgs>(client_GetNumberOfUsersOnlineCompleted);
            client.GetNumberOfUsersOnlineAsync();
        }

        void client_GetNumberOfUsersOnlineCompleted(object sender, GetNumberOfUsersOnlineCompletedEventArgs e)
        {
            if (!e.Cancelled && null == e.Error)
                NumberOfUsersOnline = e.Result;
        }

        private void LoadUsers(ConstantsUserSearchCriteria searchBy, string value)
        {
            var client = new MembershipServiceClient();
            client.GetUsersCompleted += new EventHandler<GetUsersCompletedEventArgs>(client_GetUsersCompleted);
            client.GetUsersAsync(searchBy, value);
        }

        void client_GetUsersCompleted(object sender, GetUsersCompletedEventArgs e)
        {
            if (!e.Cancelled && null == e.Error)
                BindUsersGrid(e.Result);
        }

        #endregion

        #region Data binders

        private void BindUsersGrid(ObservableCollection<UserData> memberList)
        {
            UsersList = memberList;
        }

        #endregion

        #region command handlers

        private void EditUser(object data)
        {
            if (null != this.SelectedUser)
            {
                SecurityUiHelpers.EditUserDialog(SelectedUser);
            }
        }

        private void OnAlphaFilterApplied(object data)
        {
            if (null == data || !(data is char))
                this.LoadUsers(ConstantsUserSearchCriteria.None, string.Empty);
            else
                this.LoadUsers(ConstantsUserSearchCriteria.UserName, string.Format("{0}%", data.ToString()));
        }

        #endregion
    }
}
